#include "widget.h"
#include <QDebug>
#include <QOpenGLShaderProgram>

// Create a colored triangle
static const GLfloat vertices[] =
{
    // 第一个三角形
    0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,  // 右上角
    0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 右下角
    -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, // 左上角
    // 第二个三角形
    0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下角
    -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,// 左下角
    -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f   // 左上角
};

Widget::Widget(QWidget *parent)
    : QOpenGLWidget(parent), vbo(QOpenGLBuffer::VertexBuffer)
{
    program = Q_NULLPTR;
}

Widget::~Widget()
{
    makeCurrent();
    teardownGL();
}

void Widget::initializeGL()
{
    initializeOpenGLFunctions();
    printContextInformation();

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    //
    program = new QOpenGLShaderProgram();
    program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/simple.vert");
    program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/simple.frag");
    program->link();
    program->bind();

    //
    vao.create();
    vao.bind();

    //
    vbo.create();
    vbo.bind();
    vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    vbo.allocate(vertices, sizeof(vertices));

    //
    program->enableAttributeArray(0);
    program->setAttributeBuffer(0, GL_FLOAT, 0, 3, 6 * sizeof(GLfloat));

    program->enableAttributeArray(1);
    program->setAttributeBuffer(1, GL_FLOAT, 3 * sizeof(GLfloat), 3, 6 * sizeof(GLfloat));

    //
    vbo.release();
    vao.release();
    program->release();
}

void Widget::resizeGL(int w, int h)
{
}

void Widget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    program->bind();
    vao.bind();

    qDebug() << vbo.size();
    glDrawArrays(GL_TRIANGLES, 0, sizeof(vertices) / sizeof(vertices[0]));

    vao.release();
    program->release();
}

void Widget::teardownGL()
{
    vbo.destroy();
    vao.destroy();
    delete program;
}

void Widget::printContextInformation()
{
    QString glType;
    QString glVersion;
    QString glProfile;

    // Get Version Information
    glType = (context()->isOpenGLES()) ? "OpenGL ES" : "OpenGL";
    glVersion = reinterpret_cast<const char *>(glGetString(GL_VERSION));

    // Get Profile Information
#define CASE(c) case QSurfaceFormat::c: glProfile = #c; break
    switch (format().profile())
    {
            CASE(NoProfile);
            CASE(CoreProfile);
            CASE(CompatibilityProfile);
    }
#undef CASE

    // qPrintable() will print our QString w/o quotes around it.
    qDebug() << qPrintable(glType) << qPrintable(glVersion) << "(" << qPrintable(glProfile) << ")";
}
